package edu.columbia.gate;

import java.util.Iterator;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import gate.Annotation;
import gate.Document;
import gate.ProcessingResource;
import gate.creole.AbstractController;

public class PipelineMonitor extends Thread
{
	public AbstractController gateApplication;
	public Document documentOnInterruption;
	public boolean wasInterruped = false;
	public long startTime;
	public long maximumApplicationRunTime;
	
	public PipelineMonitor(long maxAppRuntimeInMilliSecs, AbstractController gateApp)
	{
		this.maximumApplicationRunTime = maxAppRuntimeInMilliSecs;
		this.gateApplication = gateApp;
	}
	
	@Override
	public void run()
	{
		super.run();

		startTime = System.currentTimeMillis();
		documentOnInterruption = null;
		wasInterruped = false;
		long currTime = startTime;
		// Wait until the maximumApplicationRunTime has elapsed
		while(currTime - startTime < maximumApplicationRunTime)
		{
			try
			{
				// Wait half a second
				this.sleep(500L);
			}
			catch (InterruptedException ie)
			{
				// If the main program interrupts this thread at this point,
				// then we are fine, so do nothing.
				return;
			}
			currTime = System.currentTimeMillis();
		}
		GateWrapper.logger.error("Gate application is taking too long to process. It will be interrupted now.");
		try
		{
			Document doc = (Document) ((ProcessingResource) this.gateApplication.getPRs().iterator().next()).getParameterValue("document");
			this.documentOnInterruption = doc; 
			String msg = "";
			msg += "APPLICATION SEEMED TO HAVE HUNG WHILE PROCESSING DOCUMENT: " + doc.getName() + ". WAITED " + (maximumApplicationRunTime/1000) + " SECONDS FOR A DOCUMENT OF SIZE: " + doc.getContent().size() +   ".\n";
			msg += "Annotations found are:\n\t";
			SortedSet<String> annotTypes = new TreeSet<String>();
			Iterator<Annotation> annotIterator = doc.getAnnotations().iterator();
			while(annotIterator.hasNext())
				annotTypes.add(annotIterator.next().getType());
			for (String annotType : annotTypes)
				msg +=  annotType + ", ";
			msg += "\nFeatures found are:\n\t";
			Iterator<Map.Entry<Object, Object>> featIterator = doc.getFeatures().entrySet().iterator();
			while(featIterator.hasNext())
			{
				Map.Entry<Object, Object> entry = featIterator.next();
				msg += "\t" + entry.getKey().toString() + "=" + entry.getValue().toString() + "\n";
			}
			msg += "\nSTART Document content:\n";
			msg += doc.getContent().toString();
			msg += "\nEND Document content.\n";
			GateWrapper.logger.error(msg);
		} 
		catch (Exception e)
		{
			GateWrapper.logger.warn("PipelineMonitor is unable to determine current document being processed.", e);
		}
		try
		{
			wasInterruped = true;
			gateApplication.interrupt();
		} 
		catch (Exception e)
		{
			GateWrapper.logger.error("Error while interrupting gate application.", e);
		}
	}
}
